home *** CD-ROM | disk | FTP | other *** search
/ Strategy Challenges Collection / Strategy Challenges Collection.iso / pc / edinst / utility / wing / dumb3d.cp_ / dumb3d.cp
Text File  |  1994-08-13  |  8KB  |  309 lines

  1. /**************************************************************************
  2.   dumb3d.cpp - A simple linear algebra library for 3D.
  3.  
  4.  **************************************************************************/
  5. /**************************************************************************
  6.  
  7.     (C) Copyright 1994 Microsoft Corp.  All rights reserved.
  8.  
  9.     You have a royalty-free right to use, modify, reproduce and 
  10.     distribute the Sample Files (and/or any modified version) in 
  11.     any way you find useful, provided that you agree that 
  12.     Microsoft has no warranty obligations or liability for any 
  13.     Sample Application Files which are modified. 
  14.  
  15.  **************************************************************************/
  16.  
  17. //*** We're intentionally converting doubles to floats all over...
  18. #pragma warning ( 4 : 4136 )
  19.  
  20. #include"dumb3d.hpp"
  21.  
  22. #include<math.h>
  23.  
  24. /*--------------------------------------------------------------------------
  25.  
  26. matrix multiplication.
  27.  
  28. */
  29.  
  30. matrix_4x4 operator*( matrix_4x4 const &Multiplicand,
  31.     matrix_4x4 const &Multiplier )
  32. {
  33.   matrix_4x4 ReturnMatrix;
  34.  
  35.   for(int i = 0;i < 4;i++)
  36.   {
  37.     for(int j = 0;j < 4;j++)
  38.     {
  39.       real Value = 0;
  40.       
  41.       for(int k = 0;k < 4;k++)
  42.       {
  43.         Value += Multiplicand.GetElement(i,k) *
  44.             Multiplier.GetElement(k,j);
  45.       }
  46.  
  47.       ReturnMatrix.SetElement(i,j,Value);
  48.     }
  49.   }
  50.  
  51.   return ReturnMatrix;
  52. }
  53.  
  54. vector_4 operator*( matrix_4x4 const &Multiplicand,
  55.     vector_4 const &Multiplier )
  56. {
  57.   vector_4 ReturnPoint;
  58.  
  59.   for(int i = 0;i < 4;i++)
  60.   {
  61.     real Value = 0;
  62.     
  63.     for(int k = 0;k < 4;k++)
  64.     {
  65.       Value += Multiplicand.GetElement(i,k) *
  66.           Multiplier.GetElement(k);
  67.     }
  68.  
  69.     ReturnPoint.SetElement(i,Value);
  70.   }
  71.  
  72.   return ReturnPoint;
  73. }
  74.  
  75. point_4 operator*( matrix_4x4 const &Multiplicand,
  76.     point_4 const &Multiplier )
  77. {
  78.   point_4 ReturnPoint;
  79.  
  80.   for(int i = 0;i < 4;i++)
  81.   {
  82.     real Value = 0;
  83.     
  84.     for(int k = 0;k < 4;k++)
  85.     {
  86.       Value += Multiplicand.GetElement(i,k) *
  87.           Multiplier.GetElement(k);
  88.     }
  89.  
  90.     ReturnPoint.SetElement(i,Value);
  91.   }
  92.  
  93.   return ReturnPoint;
  94. }
  95.  
  96.  
  97. /*--------------------------------------------------------------------------
  98.  
  99. constructor.
  100.  
  101. */
  102.  
  103. matrix_4x4::matrix_4x4( void )
  104. {
  105.   for(int Counter = 0;Counter < 16;Counter++)
  106.   {
  107.     aElements[0][Counter] = 0;
  108.   }
  109.  
  110.   aElements[0][0] = aElements[1][1] = aElements[2][2] = aElements[3][3] = 1;
  111. }
  112.  
  113.  
  114. /*--------------------------------------------------------------------------
  115.  
  116. Rotations.
  117.  
  118. */
  119.  
  120. matrix_4x4 &matrix_4x4::ConcatenateXRotation( real Degrees )
  121. {
  122.   real Temp01, Temp11, Temp21, Temp31;
  123.   real Temp02, Temp12, Temp22, Temp32;
  124.  
  125.   real Radians = (Degrees/360) * M_PI * 2;
  126.  
  127.   real Sin = sin(Radians), Cos = cos(Radians);
  128.  
  129.   Temp01 = aElements[0][1] * Cos + aElements[0][2] * Sin;
  130.   Temp11 = aElements[1][1] * Cos + aElements[1][2] * Sin;
  131.   Temp21 = aElements[2][1] * Cos + aElements[2][2] * Sin;
  132.   Temp31 = aElements[3][1] * Cos + aElements[3][2] * Sin;
  133.  
  134.   Temp02 = aElements[0][1] * -Sin + aElements[0][2] * Cos;
  135.   Temp12 = aElements[1][1] * -Sin + aElements[1][2] * Cos;
  136.   Temp22 = aElements[2][1] * -Sin + aElements[2][2] * Cos;
  137.   Temp32 = aElements[3][1] * -Sin + aElements[3][2] * Cos;
  138.  
  139.   aElements[0][1] = Temp01;
  140.   aElements[1][1] = Temp11;
  141.   aElements[2][1] = Temp21;
  142.   aElements[3][1] = Temp31;
  143.   aElements[0][2] = Temp02;
  144.   aElements[1][2] = Temp12;
  145.   aElements[2][2] = Temp22;
  146.   aElements[3][2] = Temp32;
  147.  
  148.   return *this;
  149. }
  150.  
  151. matrix_4x4 &matrix_4x4::ConcatenateYRotation( real Degrees )
  152. {
  153.   real Temp00, Temp10, Temp20, Temp30;
  154.   real Temp02, Temp12, Temp22, Temp32;
  155.  
  156.   real Radians = (Degrees/360) * M_PI * 2;
  157.  
  158.   real Sin = sin(Radians), Cos = cos(Radians);
  159.  
  160.   Temp00 = aElements[0][0] * Cos + aElements[0][2] * -Sin;
  161.   Temp10 = aElements[1][0] * Cos + aElements[1][2] * -Sin;
  162.   Temp20 = aElements[2][0] * Cos + aElements[2][2] * -Sin;
  163.   Temp30 = aElements[3][0] * Cos + aElements[3][2] * -Sin;
  164.  
  165.   Temp02 = aElements[0][0] * Sin + aElements[0][2] * Cos;
  166.   Temp12 = aElements[1][0] * Sin + aElements[1][2] * Cos;
  167.   Temp22 = aElements[2][0] * Sin + aElements[2][2] * Cos;
  168.   Temp32 = aElements[3][0] * Sin + aElements[3][2] * Cos;
  169.  
  170.   aElements[0][0] = Temp00;
  171.   aElements[1][0] = Temp10;
  172.   aElements[2][0] = Temp20;
  173.   aElements[3][0] = Temp30;
  174.   aElements[0][2] = Temp02;
  175.   aElements[1][2] = Temp12;
  176.   aElements[2][2] = Temp22;
  177.   aElements[3][2] = Temp32;
  178.  
  179.   return *this;
  180. }
  181.  
  182. matrix_4x4 &matrix_4x4::ConcatenateZRotation( real Degrees )
  183. {
  184.   real Temp00, Temp10, Temp20, Temp30;
  185.   real Temp01, Temp11, Temp21, Temp31;
  186.  
  187.   real Radians = (Degrees/360) * M_PI * 2;
  188.  
  189.   real Sin = sin(Radians), Cos = cos(Radians);
  190.  
  191.   Temp00 = aElements[0][0] * Cos + aElements[0][1] * Sin;
  192.   Temp10 = aElements[1][0] * Cos + aElements[1][1] * Sin;
  193.   Temp20 = aElements[2][0] * Cos + aElements[2][1] * Sin;
  194.   Temp30 = aElements[3][0] * Cos + aElements[3][1] * Sin;
  195.  
  196.   Temp01 = aElements[0][0] * -Sin + aElements[0][1] * Cos;
  197.   Temp11 = aElements[1][0] * -Sin + aElements[1][1] * Cos;
  198.   Temp21 = aElements[2][0] * -Sin + aElements[2][1] * Cos;
  199.   Temp31 = aElements[3][0] * -Sin + aElements[3][1] * Cos;
  200.  
  201.   aElements[0][0] = Temp00;
  202.   aElements[1][0] = Temp10;
  203.   aElements[2][0] = Temp20;
  204.   aElements[3][0] = Temp30;
  205.   aElements[0][1] = Temp01;
  206.   aElements[1][1] = Temp11;
  207.   aElements[2][1] = Temp21;
  208.   aElements[3][1] = Temp31;
  209.  
  210.   return *this;
  211. }
  212.  
  213. /*--------------------------------------------------------------------------
  214.  
  215. Translations.
  216.  
  217. */
  218.  
  219. matrix_4x4 &matrix_4x4::ConcatenateXTranslation( real Distance )
  220. {
  221.   aElements[0][3] = aElements[0][0] * Distance + aElements[0][3];
  222.   aElements[1][3] = aElements[1][0] * Distance + aElements[1][3];
  223.   aElements[2][3] = aElements[2][0] * Distance + aElements[2][3];
  224.   aElements[3][3] = aElements[3][0] * Distance + aElements[3][3];
  225.  
  226.   return *this;
  227. }
  228.  
  229. matrix_4x4 &matrix_4x4::ConcatenateYTranslation( real Distance )
  230. {
  231.   aElements[0][3] = aElements[0][1] * Distance + aElements[0][3];
  232.   aElements[1][3] = aElements[1][1] * Distance + aElements[1][3];
  233.   aElements[2][3] = aElements[2][1] * Distance + aElements[2][3];
  234.   aElements[3][3] = aElements[3][1] * Distance + aElements[3][3];
  235.  
  236.   return *this;
  237. }
  238.  
  239. matrix_4x4 &matrix_4x4::ConcatenateZTranslation( real Distance )
  240. {
  241.   aElements[0][3] = aElements[0][2] * Distance + aElements[0][3];
  242.   aElements[1][3] = aElements[1][2] * Distance + aElements[1][3];
  243.   aElements[2][3] = aElements[2][2] * Distance + aElements[2][3];
  244.   aElements[3][3] = aElements[3][2] * Distance + aElements[3][3];
  245.  
  246.   return *this;
  247. }
  248.  
  249. /*--------------------------------------------------------------------------
  250.  
  251. vector normalize.
  252.  
  253. */
  254.  
  255. vector_4 &vector_4::Normalize( void )
  256. {
  257.   real Length = sqrt(GetX()*GetX() + GetY()*GetY() + GetZ()*GetZ());
  258.  
  259.   SetX(GetX() / Length);
  260.   SetY(GetY() / Length);
  261.   SetZ(GetZ() / Length);
  262.  
  263.   return *this;
  264. }
  265.   
  266. /*--------------------------------------------------------------------------
  267.  
  268. view transform ctor.
  269.  
  270. */
  271.  
  272. view_transform::view_transform( point_4 const &Viewpoint,
  273.   vector_4 const &ViewDirection, vector_4 const &Up )
  274. {
  275.   // translate the viewpoint to the origin
  276.  
  277.   this->ConcatenateXTranslation(-Viewpoint.GetX());
  278.   this->ConcatenateYTranslation(-Viewpoint.GetY());
  279.   this->ConcatenateZTranslation(-Viewpoint.GetZ());
  280.  
  281.   // get view vectors set up
  282.  
  283.   vector_4 Right = -CrossProduct(ViewDirection,Up);
  284.   vector_4 ReallyUp = CrossProduct(Right,ViewDirection);
  285.     
  286.   matrix_4x4 LookDownZ;
  287.  
  288.   for(int Counter = 0;Counter < 3;Counter++)
  289.   {
  290.     LookDownZ.SetElement(0,Counter,Right.GetElement(Counter));
  291.   }
  292.  
  293.   for(Counter = 0;Counter < 3;Counter++)
  294.   {
  295.     LookDownZ.SetElement(1,Counter,ReallyUp.GetElement(Counter));
  296.   }
  297.  
  298.   for(Counter = 0;Counter < 3;Counter++)
  299.   {
  300.     LookDownZ.SetElement(2,Counter,ViewDirection.GetElement(Counter));
  301.   }
  302.  
  303.   this->matrix_4x4::operator=(LookDownZ * *this);
  304. }
  305.  
  306. //*** Turn on float conversion warning
  307. #pragma warning ( default : 4136 )
  308.  
  309.